package com.mcintyret.site.service.users.registration;

import com.mcintyret.site.users.User;
import com.mcintyret.site.users.UserFactory;
import com.mcintyret.site.users.database.UsersDao;
import com.mcintyret.site.validation.password.PasswordValidator;
import com.mcintyret.site.web.controller.users.forms.RegistrationForm;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * User: mcintyret2
 * Date: 07/04/2012
 */

@Service
public class RegistrationManager {

    @Resource
    private UsersDao usersDao;
    @Resource
    private AuthenticationManager authenticationManager;
    @Resource
    private HttpServletRequest request;
    @Resource
    private PasswordValidator passwordValidator;
    @Resource
    private UserFactory userFactory;

    private void loginNewUser(String username, String password) {
        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(username,
                                                                                                     password);
        authentication.setDetails(new WebAuthenticationDetails(request));
        Authentication authenticatedUser = authenticationManager.authenticate(authentication);

        SecurityContextHolder.getContext().setAuthentication(authenticatedUser);
    }

    @Transactional("usersTransactionManager")
    public boolean registerAndLoginNewUser(RegistrationForm form, BindingResult errors) {
        String username = form.getUsername();
        String password = form.getPassword();

        passwordValidator.validatePassword(password, errors);

        if (usersDao.retrieveUser(username) == null) {
            // Username doesn't already exist - success!
            if (!errors.hasErrors()) {
                User newUser = userFactory.newNormalUser(username, password, form.getEmail());
                usersDao.createNewUser(newUser);
            }
        } else {
            errors.rejectValue("username", "com.mcintyret.constraints.username.alreadyexists",
                               new Object[]{username}, "Username already exists - please use another one");
        }

        if (errors.hasErrors()) {
            return false;
        } else {
            loginNewUser(username, password);
            return true;
        }
    }

}
